Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace PageRevision with generic Revision model #8441

Merged
merged 64 commits into from
May 17, 2022

Conversation

laymonage
Copy link
Member

@laymonage laymonage commented Apr 27, 2022

This PR replaces the PageRevision model with a more generic Revision model. Instead of using a ForeignKey directly to the Page model, we're using a CharField object_id and a couple of ForeignKeys to the ContentType model. We are not using the GenericForeignKey field due to complexities it adds when handling the default/specific Page models (see also ticket 16055 in Django). However, we try to simulate the same behaviour as the GenericForeignKey wherever possible.

Please check the following:

  • Do the tests still pass?1
  • Does the code comply with the style guide?
    • Run make lint from the Wagtail root.
  • For Python changes: Have you added tests to cover the new/fixed behaviour?
  • For front-end changes: Did you test on all of Wagtail’s supported environments?2
    • Please list the exact browser and operating system versions you tested:
    • Please list which assistive technologies 3 you tested:
  • For new features: Has the documentation been updated accordingly?

Please describe additional details for testing this change.

Footnotes

  1. Development Testing

  2. Browser and device support

  3. Accessibility Target

@squash-labs
Copy link

squash-labs bot commented Apr 27, 2022

Manage this branch in Squash

Test this branch here: https://laymonagegeneric-revision-ais9h.squash.io

Copy link
Member Author

@laymonage laymonage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some initial updates to the docs. Might need to get a better decision on the page property, though. Kindly review @kaedroho, thanks!

wagtail/admin/views/home.py Show resolved Hide resolved
wagtail/models/__init__.py Show resolved Hide resolved
Comment on lines 2226 to 2270
@cached_property
def page(self):
return self.content_object

@cached_property
def page_id(self):
return int(self.object_id)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should either get rid of this now or add some documentation and deprecation warning and get rid of this later. Or maybe leave this in as a shorthand, but make it undocumented?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't got a strong opinion on this. @gasman what do you think?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd go for the deprecation. It seems like something people are likely to be using in the wild, but that we don't want to keep around indefinitely.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be removed in Wagtail 5.0, or 6.0?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's say 5.0, since we don't know at this point how far into the future 5.0 and 6.0 are going to be. (I know this tripped us up with use_json_field, and we're still figuring things out - but I think we can make it work as long as we hold off on doing the actual removals for version N until version N-1 has been released and bakerydemo is updated accordingly).

Copy link
Member Author

@laymonage laymonage May 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, thanks! I've added the deprecation warnings. Let me know if there are any changes needed.

Revision.objects.all().update(
base_content_type=page_type,
content_type_id=Cast(
KeyTextTransform("content_type", models.F("content")),
Copy link
Member Author

@laymonage laymonage Apr 29, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out we can't cast jsonb into integer directly. We need to extract the value as text using the ->> operator before casting it. So, instead of doing content__content_type (which implicitly use the KeyTransform's -> operator), we should use KeyTextTransform, which extracts the value using the ->> operator.

See:

Note: both transforms work the same way on other database backends, so this isn't an issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!

Sounds like we should manually test this one on SQLite/MySQL to make sure the behaviour is the same

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've confirmed that it works on SQLite.

I haven't tested the migration on MySQL, but the query should work:

https://www.db-fiddle.com/f/gNvMtEFUYh2drgBAKjqiL5/0

Anyway, the distinction is only made for PostgreSQL anyway:

https://github.com/django/django/blob/27b07a3246bc033cd9ded01238c6dc64731cce35/django/db/models/fields/json.py#L366-L368

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey y'all,

When I install the current main with this PR's commits on bakerydemo, with a fresh SQLite database, and run migrations for the first time, it errors out on 0070 with the following:

django.db.utils.NotSupportedError: Renaming the 'wagtailcore_pagerevision' table while in a transaction is not supported on SQLite < 3.26 because it would break referential integrity. Try adding atomic = False to the Migration class.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the report, for some reason I did not run into that issue but it seems others have run into it too. We can continue the discussion in #8635.

@laymonage laymonage marked this pull request as ready for review April 29, 2022 16:28
@kaedroho kaedroho requested review from gasman and kaedroho May 3, 2022 10:36
@laymonage laymonage force-pushed the generic-revision branch from afa8d86 to d77d1f0 Compare May 4, 2022 05:19
wagtail/models/__init__.py Outdated Show resolved Hide resolved
wagtail/models/__init__.py Outdated Show resolved Hide resolved
docs/reference/pages/model_reference.rst Outdated Show resolved Hide resolved
docs/reference/pages/model_reference.rst Outdated Show resolved Hide resolved
docs/releases/4.0.md Outdated Show resolved Hide resolved
Revision.objects.all().update(
base_content_type=page_type,
content_type_id=Cast(
KeyTextTransform("content_type", models.F("content")),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one!

Sounds like we should manually test this one on SQLite/MySQL to make sure the behaviour is the same

wagtail/migrations/0072_alter_revision_content_type.py Outdated Show resolved Hide resolved
wagtail/models/__init__.py Outdated Show resolved Hide resolved
@laymonage laymonage force-pushed the generic-revision branch 7 times, most recently from d0bcba9 to bbc9d98 Compare May 16, 2022 10:09
Copy link
Collaborator

@gasman gasman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really happy with this! Just a couple of documentation nitpicks.

docs/reference/pages/model_reference.rst Outdated Show resolved Hide resolved
docs/releases/4.0.md Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants